import { Mini3d, Resource } from "mini3d";
import * as THREE from "three";
import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js";
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import GUI from "three/examples/jsm/libs/lil-gui.module.min.js";
import { UnrealBloomPass } from "./UnrealBloomPass";
import { EmissivePass } from "./EmissivePass";
import { MixPass } from "./MixPass";
// import { DemoPass } from "./DemoPass";

const assets = [
  { name: "demo", type: "GLTF", path: "/demo.gltf" },
  { name: "demo2", type: "GLTF", path: "/demo2.gltf" },
  { name: "demo3", type: "GLTF", path: "/demo3.gltf" },
];

export class AppScene extends Mini3d {
  resource = new Resource();
  gui = new GUI();
  emissiveEffect?: EffectComposer;

  constructor(canvas: HTMLCanvasElement) {
    super(canvas);

    this.renderer.instance.outputColorSpace = THREE.SRGBColorSpace;
    const directLight = new THREE.DirectionalLight(0xffffff, 1);
    const ambientLight = new THREE.AmbientLight(0xa8a4a4, 1);

    this.scene.add(directLight, ambientLight);

    this.initEffect();
    this.resource.loadAll(assets).then(() => {
      this.init();
    });
  }

  initEffect() {
    const emissiveEffect = new EffectComposer(this.renderer.instance);
    this.emissiveEffect = emissiveEffect;
    emissiveEffect.renderToScreen = false;
    emissiveEffect.addPass(new EmissivePass(this.scene, this.camera.instance));
    const unrealBloomPass = new UnrealBloomPass(
      new THREE.Vector2(
        this.sizes.width * this.sizes.pixelRatio,
        this.sizes.height * this.sizes.pixelRatio
      ),
      0.5,
      0.1
    );
    emissiveEffect.addPass(unrealBloomPass);
    const loomGui = this.gui.addFolder("unrealBloomPass");
    loomGui.add(unrealBloomPass, "strength", 0, 10);
    loomGui.add(unrealBloomPass, "radius", 0, 10);

    // emissiveEffect.addPass(new OutputPass());
    // this.renderer.composer = emissiveEffect;
    // this.renderer.postprocessing = true;
    // return;

    // 最终effect
    const finalEffect = new EffectComposer(this.renderer.instance);
    finalEffect.addPass(new RenderPass(this.scene, this.camera.instance));

    // 混合其他纹理
    const mixPass = new MixPass({
      texture: emissiveEffect.renderTarget2.texture,
    });
    finalEffect.addPass(mixPass);

    finalEffect.addPass(new OutputPass());

    const oldRender = finalEffect.render;
    finalEffect.render = (...args) => {
      // console.log("effect.render");
      oldRender.call(finalEffect, ...args);
    };
    this.renderer.composer = finalEffect;
    this.renderer.postprocessing = true;
  }

  update(deltaTime: number) {
    if (this.emissiveEffect) {
      this.emissiveEffect.render();
    }
    super.update(deltaTime);
  }

  init() {
    const demo = this.resource.getResource("demo3");
    const demoScene = demo.scene as THREE.Object3D;
    this.scene.add(demoScene);
    console.log(demoScene);
  }
}
